#ifndef _HOOK_H_
#define _HOOK_H_

#include <stdint.h>


#define nasm(n) asm(n"\n");

typedef int32_t s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef u32 (*hook_func_t)();

#define IPC_OPEN_NONE		  0
#define IPC_OPEN_READ		  1
#define IPC_OPEN_WRITE		  2
#define IPC_OPEN_RW			  (IPC_OPEN_READ|IPC_OPEN_WRITE)

#define IOS_Open(fp,mode)          ((hook_func_t)0x80391750)(fp,mode)
#define IOS_Read(fd,buf,len)                   ((hook_func_t)0x80391994)(fd,buf,len)
#define IOS_Write(fd,buf,len)                  ((hook_func_t)0x80391A58)(fd,buf,len)
#define IOS_Seek(fd,where,whence)          ((hook_func_t)0x80391904)(fd,where,whence)
#define IOS_Close(fd)         ((hook_func_t)0x80391B1C)(fd)

/*

80393E24(F,buf,size)
802A36EC(,F)
    会调用80393E24,一次读取0x100

*/
//FILE?
typedef struct{
    int fd;
}F;

/*
8001C7DC
    类似fprintf ?
    fprintf(struct,format,...)


    他们最终都会调用80380EFC

*/

#define xsprintf(...)     ((hook_func_t)0x80381A70)(__VA_ARGS__)

#define CALL(addr,...) ((hook_func_t)addr)(__VA_ARGS__)
//#define IOS_GetFileStatus           ((hook_func_t)0x803918D0)
//#define IOS_GetMeta       ((hook_func_t)0x80390EF8)

typedef struct{
    u32 lr;
    u32 r3,r4,r5,r6;
    u32 sp;
    u32 hook_func;
    u32 extend_func;    //
    u32 text_fd;        //文本id
    int extend_fd;
    int font_fd;
    int other_text_fd;
    int lock;
    char *text;
    u8  log[128];
}_save_t;

#define EXTEND_ADDR 0x81000000
#if 1
#define SAVE ((_save_t*)(EXTEND_ADDR-0x100))
#endif

#include <stdarg.h>


#define GAME_PATH "/title/00010000/5233354a/data/"
#define HOOK_RESTORE_FILE GAME_PATH"hook_func.bin"
#define EXTEND_EXE  GAME_PATH"extend.bin"
#define LOG_FILE    GAME_PATH"log.txt"
#define TEXT_FILE   GAME_PATH"game.txt"
#define ALL_TEXT_FILE   GAME_PATH"all.txt"
#define ALLID_TEXT_FILE   GAME_PATH"all_id.txt"
#define ID_TRANSLATE_FILE   GAME_PATH"id_translate.txt"
#define HOOK_LIST   GAME_PATH"hook.txt"
#define FONT_FILE   GAME_PATH"font.bin"
#define HOOK_RETURN_ADDR 0x80fffe00

#ifdef _INC_STRING
static void* strcpy(char*a1,char*a2){
    while(*a2){
        *a1 = *a2;
        a1++;
        a2++;
    }
    a1[0] = 0;
    return a1;
}

static int strlen(char*a1){
    int off = 0;
    while(*a1){
        a1++;
        off++;
    }
    return off;
}
#endif

#if 0
static void* memcpy(u8*a1,u8*a2,int sz){
    while(sz>0){
        *a1 = *a2;
        a1++;
        a2++;
        sz --;
    }
    return a1;
}
#else
#ifdef _INC_STRING
static void* memcpy(void*a1,void*a2,int sz){
    return (void*)CALL(0x80004338,a1,a2,sz);
}
#endif

static void* memcpy4(void*a1,void*a2,int sz){
    u32*p1 = a1;
    u32*p2 = a2;
    while(sz>0){
        *p1 = *p2;
        p1 ++;
        p2 ++;
        sz -= 4;
    }
}
#endif

static void* xmemset(void*a,int v,int sz){
    u8 *a1 = (u8*)a;
    u32 value = v|(v<<8)|(v<<16)|(v<<24);
    while(sz>3){
        *(u32*)a1 = value;
        a1 += 4;
        sz -= 4;
    }
    while(sz>1){
        *(u16*)a1 = value;
        a1 += 2;
        sz -= 2;
    }
    while(sz>0){
        *a1 = v;
        a1++;
        sz --;
    }
    return a1;
}

#define LR 32
#define CR 33
#define CTR 34
#define SP 1
#define RESULT 3
#define PARAM 3
typedef struct{
    u32     reg[0x30];
}hook_cpu_t;


typedef struct{
    char* ptr;
    int   len;
}id_text_str;

typedef struct{
    u32   base;         //字符串的位置
    u32   end_text;     //结束位置
    //char* ptr[0x3000];  //id字符串表
    id_text_str str[0x3000];
    char  text[1];
}id_text_t;

#endif
